package dryven.unittest;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import dryven.discovery.TypeUtil;
import dryven.reflection.TypeRef;
import junit.framework.TestCase;

public class TypeUtilTestCase extends TestCase {
	public void testTypeUtil() {
		checkTypeValue(TypeUtil.parseTypeName("I"), Integer.class.getName(), 0, false, true);
		checkTypeValue(TypeUtil.parseTypeName("[[[Z"), Boolean.class.getName(), 3, false, true);
		checkTypeValue(TypeUtil.parseTypeName("[[[Ljava/lang/String;"), String.class.getName(), 3, false, true);
		checkTypeValue(TypeUtil.parseTypeName("[[[Ljava/lang-String;"), String.class.getName(), 3, false, false);
		TypeRef v = TypeUtil.parseTypeName("[[Ljava/util/Map<Ljava/lang/String;Ljava/lang/Integer;>;");
		assertTrue(v.getTypeName().equals(Map.class.getName()));
		assertTrue(v.getArrayDimensions()==2);
		assertTrue(v.isGeneric());
		Class[] refclasses = {String.class,Integer.class};
		int index = 0;
		for (TypeRef genp : v.getGenericTypeParams()) {
			Class ref = refclasses[index];
			++index;
			assertTrue(genp.getTypeName().equals(ref.getName()));
		}
		assertTrue(index==2);
		
		v = TypeUtil.parseTypeName("Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;>;");
		assertTrue(v.getTypeName().equals(Map.class.getName()));
		assertFalse(v.isArray());
		assertTrue(v.isGeneric());
		ArrayList<TypeRef> genericParams = new ArrayList<TypeRef>();
		for (TypeRef typeValue : v.getGenericTypeParams()) {
			genericParams.add(typeValue);
		}
		assertTrue(genericParams.size()==2);
		assertTrue(genericParams.get(0).getTypeName().equals(String.class.getName()));
		assertFalse(genericParams.get(0).isGeneric());
		assertTrue(genericParams.get(1).getTypeName().equals(List.class.getName()));
		assertTrue(genericParams.get(1).isGeneric());
		assertTrue(genericParams.get(1).getGenericTypeParams().iterator().next().getTypeName().equals(String.class.getName()));
		
		TypeRef[] tvs = TypeUtil.parseSignature(new StringReader("(FIFILjava/lang/String;Z)"));
		Class[] ref = new Class[] {Float.class, Integer.class, Float.class, Integer.class, String.class, Boolean.class};
		assertTrue(tvs.length==ref.length);
		for(int i = 0;i<ref.length;++i) {
			assertTrue(tvs[i].getTypeName().equals(ref[i].getName()));
		}
	}
	
	private void checkTypeValue(TypeRef v, String className, int arrayDim, boolean isGeneric, boolean refValue) {
		assertEquals(refValue,v.getTypeName().equals(className) && v.getArrayDimensions()==arrayDim && v.isGeneric()==isGeneric);
	}
}
